// SSE音频播放功能 - 无DOM依赖版本
// 定义SSE音频播放器类
class SSEAudioPlayer {
  constructor(options = {}) {
    // 默认配置
    this.config = {
      host: options.host || 'https://tbbs-api.chinesemir.com/sse-audio.php',
      endpoint: options.endpoint || '/tts'
    };

    // 初始化
    this.init();
    }

  // 初始化函数
  init() {

      // 保存上一次的请求参数
      this.lastRequestParams = null;

      // 初始化音频相关变量
      this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
      this.audioQueue = [];
      this.isPlaying = false;
      this.isPaused = false;
      this.pausedPosition = 0;
      this.pausedBuffer = null;
      this.audioSource = null;
      this.isProcessing = false;
      this.currentChunkIndex = 0;
      this.totalPlaybackTime = 0;
      this.startTime = 0;
      this.bgmPausedTime = 0;
      // 初始化第一个数据提取相关的变量
      this.firstDataExtracted = false;
      this.firstDataUrl = null;
      this.firstDataWorkId = null;
      this.firstChunkDecoded = false; // 标记第一个音频块是否已解码
      this.firstChunkDecoded = false; // 重置第一个音频块解码标记
      
      // 数据加载状态
      this.isDataLoaded = false; // 标记数据是否已加载完成
      this.autoPlay = false; // 是否自动播放

      // iOS SSE 连接管理
      this.sseReader = null;
      this.sseAbortController = null;
      this.reconnectAttempts = 0;
      this.maxReconnectAttempts = 3;
      this.lastReceivedTime = 0;
      this.heartbeatTimer = null;

      // 音频块合并相关变量
      this.mergeBuffer = []; // 用于暂存待合并的音频块
      this.mergeCount = 10; // 每次合并10个音频块(减少等待，提高流畅度)
      this.receivedChunkCount = 0; // 已接收的总音频块数量
      this.streamEnded = false; // 标记流是否已结束
      this.initialChunksProcessed = false; // 标记是否已处理开头的音频块

      // 预解码队列,存储已解码但未播放的AudioBuffer
      this.decodedQueue = [];
      this.isDecoding = false;

      // 音频播放状态锁，防止并发播放
      this.isPlayingChunk = false;

  }

  /**
   * 派发自定义事件
   * @param {string} eventName - 事件名称
   * @param {object} detail - 事件详情数据
   */
  dispatchEvent(eventName, detail = {}) {
    const event = new CustomEvent(eventName, { detail });
    document.dispatchEvent(event);
    console.log(`[SSEAudioPlayer] 派发事件: ${eventName}`, detail);
  }

  /**
   * 加载音频数据（外部调用）
   * @param {object} formData - 表单数据 { speakerId, uid, artifactId, text }
   */
  loadAudioData(formData) {
    console.log('→ 加载数据模式，设置 autoPlay = false');
    
    // iOS 设备：播放静默音频解锁 AudioContext
    this.unlockAudioContext();

    // 保存请求参数用于重新播放
    this.lastRequestParams = formData;

    // 准备加载环境
    this.prepareLoading();

    // 发送请求并处理音频流（不自动播放）
    this.autoPlay = false;
    console.log('→ autoPlay 已设置为:', this.autoPlay);
    this.fetchAudioStream(formData);
  }
    
  /**
   * 开始播放音频（外部调用，加载并自动播放）
   * @param {object} formData - 表单数据 { speakerId, uid, artifactId, text }
   */
  startPlayback(formData) {
    console.log('→ 一键播放模式，设置 autoPlay = true');
    
    // iOS 设备：播放静默音频解锁 AudioContext
    this.unlockAudioContext();

    // 保存请求参数用于重新播放
    this.lastRequestParams = formData;

    // 准备播放环境
    this.preparePlayback();

    // 发送请求并处理音频流（自动播放）
    this.autoPlay = true;
    console.log('→ autoPlay 已设置为:', this.autoPlay);
    this.fetchAudioStream(formData);
  }
    
  /**
   * 播放已加载的音频（外部调用）
   */
  startPlaying() {
    if (!this.isDataLoaded) {
      console.warn('请先加载音频数据');
      this.dispatchEvent('sseAudioPlayer:error', { 
        message: '请先加载音频数据',
        code: 'NO_DATA'
      });
      return;
    }
    
    if (this.isPlaying) {
      console.warn('音频正在播放中');
      return;
    }
    
    // iOS 设备：播放静默音频解锁 AudioContext
    this.unlockAudioContext();
    
    // 开始播放
    if (this.decodedQueue.length > 0 || this.audioQueue.length > 0) {
      this.playFirstAudioChunk();
    } else {
      console.warn('没有可播放的音频数据');
      this.dispatchEvent('sseAudioPlayer:error', { 
        message: '没有可播放的音频数据',
        code: 'NO_AUDIO_DATA'
      });
    }
  }



  // 准备加载环境
  prepareLoading() {

      // 清理之前的 SSE 连接
      this.cleanupSSEConnection();

      // 先停止并清理当前正在播放的音频源
      if (this.audioSource) {
        try {
          this.audioSource.stop();
          this.audioSource.disconnect();
        } catch (e) {
          console.warn('清理音频源时出错:', e);
        }
        this.audioSource = null;
      }

      // 清空音频队列和缓冲区,避免重复播放残留数据
      this.audioQueue = [];
      this.mergeBuffer = [];
      this.decodedQueue = [];
      this.receivedChunkCount = 0;
      this.isPlaying = false;
      this.isPaused = false;
      this.pausedPosition = 0;
      this.pausedBuffer = null;
      this.isProcessing = false;
      this.isDecoding = false;
      this.currentChunkIndex = 0;
      this.totalPlaybackTime = 0;
      this.startTime = 0;
      this.bgmPausedTime = 0;
      this.firstDataExtracted = false;
      this.firstDataUrl = null;
      this.firstDataWorkId = null;
      this.firstChunkDecoded = false; // 重置第一个音频块解码标记
      this.streamEnded = false; // 重置流结束标记
      this.initialChunksProcessed = false; // 重置开头音频块处理标记
      this.reconnectAttempts = 0; // 重置重连次数
      this.isDataLoaded = false; // 重置数据加载标记
    }
    
  // 准备播放环境
  preparePlayback() {

      // 清理之前的 SSE 连接
      this.cleanupSSEConnection();

      // 先停止并清理当前正在播放的音频源
      if (this.audioSource) {
        try {
          this.audioSource.stop();
          this.audioSource.disconnect();
        } catch (e) {
          console.warn('清理音频源时出错:', e);
        }
        this.audioSource = null;
      }

      // 清空音频队列和缓冲区,避免重复播放残留数据
      this.audioQueue = [];
      this.mergeBuffer = [];
      this.decodedQueue = [];
      this.receivedChunkCount = 0;
      this.isPlaying = false;
      this.isPaused = false;
      this.pausedPosition = 0;
      this.pausedBuffer = null;
      this.isProcessing = false;
      this.isDecoding = false;
      this.currentChunkIndex = 0;
      this.totalPlaybackTime = 0;
      this.startTime = 0;
      this.bgmPausedTime = 0;
      this.firstDataExtracted = false;
      this.firstDataUrl = null;
      this.firstDataWorkId = null;
      this.firstChunkDecoded = false; // 重置第一个音频块解码标记
      this.streamEnded = false; // 重置流结束标记
      this.initialChunksProcessed = false; // 重置开头音频块处理标记
      this.reconnectAttempts = 0; // 重置重连次数
    }



    // 格式化时间（秒）为mm:ss格式
    formatTime(seconds) {
      const mins = Math.floor(seconds / 60);
      const secs = Math.floor(seconds % 60);
      return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
    }

    // 播放单个音频块
    async playAudioChunk(audioBuffer) {
      // 等待上一个音频块播放完成
      while (this.isPlayingChunk) {
        await new Promise(resolve => setTimeout(resolve, 10));
      }

      this.isPlayingChunk = true;

      return new Promise((resolve) => {
        // 如果是从暂停位置恢复，同一缓冲且记录了暂停偏移，则从偏移继续
        if (this.pausedBuffer === audioBuffer && this.pausedPosition > 0) {
          // 确保停止之前的音频源（防护措施）
          if (this.audioSource) {
            try {
              this.audioSource.stop();
              this.audioSource.disconnect();
            } catch (e) {
              console.warn('停止之前的音频源时出错:', e);
            }
            this.audioSource = null;
          }

          // 创建新的音频源
          this.audioSource = this.audioContext.createBufferSource();
          this.audioSource.buffer = audioBuffer;
          this.audioSource.connect(this.audioContext.destination);
          // 从暂停位置开始播放
          this.audioSource.start(0, this.pausedPosition);

          // 音频播放完成时的回调
          this.audioSource.onended = () => {
            // 立即清理音频源，避免下一个块检测到未清理的源
            const currentSource = this.audioSource;
            this.audioSource = null;

            // 更新总播放时间
            this.totalPlaybackTime += audioBuffer.duration;

            // 更新当前音频块索引
            this.currentChunkIndex++;

            // 更新当前音频块信息显示
            const formattedTime = this.formatTime(this.totalPlaybackTime);
            console.log('✓ 音频块播放完成，索引:', this.currentChunkIndex - 1, '播放时间:', this.totalPlaybackTime);
            
            // 派发正在播放事件
            this.dispatchEvent('sseAudioPlayer:playing', {
              currentChunkIndex: this.currentChunkIndex,
              totalPlaybackTime: this.totalPlaybackTime,
              formattedTime: formattedTime,
              queueLength: this.decodedQueue.length
            });

            this.isPaused = false;
            this.pausedBuffer = null;
            this.pausedPosition = 0;

            // 断开音频节点连接
            if (currentSource) {
              try {
                currentSource.disconnect();
              } catch (e) {
                // 忽略断开连接的错误
              }
            }

            // 释放播放锁
            this.isPlayingChunk = false;

            // onended后微小延迟，确保拼接更平滑
            setTimeout(() => resolve(), 10);
          };
        } else {
          // 正常播放流程：确保之前的音频源已结束
          // 防护：如果还有正在播放的音频源，停止它
          if (this.audioSource) {
            // 只有在非正常播放结束的情况下才显示警告
            if (!this.isPaused) {
              console.warn('⚠️ 检测到未结束的音频源，强制停止');
              console.warn('   当前索引:', this.currentChunkIndex);
              console.warn('   队列中音频块数量:', this.decodedQueue.length);
              console.warn('   调用堆栈:', new Error().stack);
            }
            try {
              this.audioSource.stop();
              this.audioSource.disconnect();
            } catch (e) {
              console.warn('停止之前的音频源时出错:', e);
            }
            this.audioSource = null;
          }

          // 创建新的音频源
          this.audioSource = this.audioContext.createBufferSource();
          this.audioSource.buffer = audioBuffer;
          this.audioSource.connect(this.audioContext.destination);

          // 如果是第一个音频块，记录开始时间
          if (this.startTime === 0) {
            this.startTime = this.audioContext.currentTime;
          }

          // 开始播放
          this.audioSource.start();

          // 音频播放完成时的回调
          this.audioSource.onended = () => {
            // 立即清理音频源，避免下一个块检测到未清理的源
            const currentSource = this.audioSource;
            this.audioSource = null;

            // 更新总播放时间
            this.totalPlaybackTime += audioBuffer.duration;

            // 更新当前音频块索引
            this.currentChunkIndex++;

            // 更新当前音频块信息显示
            const formattedTime = this.formatTime(this.totalPlaybackTime);
            console.log('✓ 音频块播放完成，索引:', this.currentChunkIndex - 1, '播放时间:', this.totalPlaybackTime);

            // 派发正在播放事件
            this.dispatchEvent('sseAudioPlayer:playing', {
              currentChunkIndex: this.currentChunkIndex,
              totalPlaybackTime: this.totalPlaybackTime,
              formattedTime: formattedTime,
              queueLength: this.decodedQueue.length
            });

            // 断开音频节点连接
            if (currentSource) {
              try {
                currentSource.disconnect();
              } catch (e) {
                // 忽略断开连接的错误
              }
            }

            // 释放播放锁
            this.isPlayingChunk = false;

            // onended后微小延迟，确保拼接更平滑
            setTimeout(() => resolve(), 10);
          };
        }
      });
    }

    // 合并多个ArrayBuffer
    mergeArrayBuffers(buffers) {
      // 计算总长度
      const totalLength = buffers.reduce((sum, buffer) => sum + buffer.byteLength, 0);
      // 创建新的ArrayBuffer
      const result = new Uint8Array(totalLength);
      let offset = 0;

      // 依次复制每个buffer
      for (const buffer of buffers) {
        result.set(new Uint8Array(buffer), offset);
        offset += buffer.byteLength;
      }

      return result.buffer;
    }

    // 预解码音频数据,提前解码减少播放间隙
    async preDecodeAudio() {
      // 即使在流结束时，也要处理剩余的音频队列
      if (this.isDecoding || (this.audioQueue.length === 0 && !this.streamEnded)) return;

      this.isDecoding = true;

      try {
        // 批量解码队列中的音频数据
        while (this.audioQueue.length > 0 && this.decodedQueue.length < 3) {
          const audioData = this.audioQueue.shift();
          try {
            const audioBuffer = await this.audioContext.decodeAudioData(audioData.slice(0));
            this.decodedQueue.push(audioBuffer);
            console.log(`预解码完成,已解码队列: ${this.decodedQueue.length}, 待解码队列: ${this.audioQueue.length}`);
            
            // 派发数据加载到可播放状态事件（当第一个音频块解码完成时）
            if (this.decodedQueue.length === 1 && !this.firstChunkDecoded) {
              this.firstChunkDecoded = true;
              this.dispatchEvent('sseAudioPlayer:readyToPlay', {
                decodedQueueLength: this.decodedQueue.length,
                audioQueueLength: this.audioQueue.length
              });
            }
          } catch (e) {
            console.error('预解码音频数据错误:', e);
          }
        }
      } finally {
        this.isDecoding = false;
      }
    }

    // 处理音频队列(使用预解码队列)
    async processAudioQueue() {
      // 即使在流结束时，也要处理所有剩余的已解码音频块
      if (this.isProcessing || this.decodedQueue.length === 0 || this.isPaused) return;

      this.isProcessing = true;

      try {
        while (this.decodedQueue.length > 0 && !this.isPaused) {
          const audioBuffer = this.decodedQueue.shift();

          // 如果是第一个音频块，启动bgm
          // if (this.currentChunkIndex === 0) {
          //   if (this.bgm) {
          //     this.bgm.currentTime = 0;
          //     this.bgm.play().catch(e => console.error('播放BGM失败:', e));
          //   }
          // }

          // 播放音频块
          await this.playAudioChunk(audioBuffer);

          // 更新显示信息
          // 派发加载进度事件
          this.dispatchEvent('sseAudioPlayer:loadProgress', {
            decodedQueueLength: this.decodedQueue.length,
            audioQueueLength: this.audioQueue.length
          });

          // 如果解码队列不足,触发预解码
          if (this.decodedQueue.length < 2 && this.audioQueue.length > 0) {
            this.preDecodeAudio();
          }

          // 如果流已结束且没有更多音频块，跳出循环
          if (this.streamEnded && this.decodedQueue.length === 0 && this.audioQueue.length === 0) {
            break;
          }
        }
      } finally {
        this.isProcessing = false;

        // 如果暂停但队列中还有数据，保存当前状态并继续预解码
        if (this.isPaused && (this.decodedQueue.length > 0 || this.audioQueue.length > 0)) {
          // 暂停时继续预解码，确保恢复播放时立即可用
          if (this.audioQueue.length > 0 && this.decodedQueue.length < 3) {
            this.preDecodeAudio();
          }
        } else if (this.decodedQueue.length > 0 || this.audioQueue.length > 0) {
          // 继续预解码和播放（仅在正在播放时）
          if (this.audioQueue.length > 0 && this.decodedQueue.length < 2) {
            this.preDecodeAudio();
          }
          if (this.decodedQueue.length > 0 && !this.isPaused && this.isPlaying) {
            this.processAudioQueue();
          }
        } else if (this.streamEnded && this.decodedQueue.length === 0 && this.audioQueue.length === 0) {
          // 如果流已结束且所有音频都已播放完毕，标记播放完成
          this.resetButton();

          // 派发音频播放完成事件
          this.dispatchEvent('sseAudioPlayer:playCompleted', {
            totalPlaybackTime: this.totalPlaybackTime,
            totalChunks: this.currentChunkIndex
          });
        }
      }
    }

    // 播放第一个音频块(使用预解码)
    async playFirstAudioChunk() {
      // 即使在流结束时，只要有已解码的音频块也可以播放
      if ((this.audioQueue.length > 0 || this.decodedQueue.length > 0) && !this.isPlaying) {
        this.isPlaying = true;

        try {
          // 先预解码第一批音频（如果还有音频队列）
          if (this.audioQueue.length > 0) {
            await this.preDecodeAudio();
          }

          if (this.decodedQueue.length > 0) {
            const audioBuffer = this.decodedQueue.shift();

            // 启动bgm
            // if (this.bgm) {
            //   this.bgm.currentTime = 0;
            //   this.bgm.play().catch(e => console.error('播放BGM失败:', e));
            // }

            // 播放音频块
            await this.playAudioChunk(audioBuffer);

            // 更新显示信息
            // 派发加载进度事件
            this.dispatchEvent('sseAudioPlayer:loadProgress', {
              decodedQueueLength: this.decodedQueue.length,
              audioQueueLength: this.audioQueue.length
            });

            // 继续预解码和处理剩余音频块
            if (this.audioQueue.length > 0) {
              this.preDecodeAudio();
            }
            this.processAudioQueue();
          }
        } catch (e) {
          console.error('解码第一个音频块错误:', e);
        } finally {
          this.isPlaying = false;
        }
      }
    }

    // 解析Base64音频数据
    parseBase64AudioData(base64Data) {
      const binaryString = atob(base64Data);
      const bytes = new Uint8Array(binaryString.length);

      for (let i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
      }
      return bytes.buffer;
    }

  // 重置播放按钮状态
  resetButton() {
    // 清理 SSE 连接
    this.cleanupSSEConnection();

    this.isPaused = false;
    this.pausedBuffer = null;
    this.pausedPosition = 0;
    this.currentChunkIndex = 0;
    this.totalPlaybackTime = 0;
    this.startTime = 0;
    this.bgmPausedTime = 0;
  }

  /**
   * 切换暂停/恢复状态（外部调用）
   */
  togglePause() {
    if (!this.audioContext) return;

    if (this.isPaused) {
      // 从暂停状态恢复播放
      this.isPaused = false;
      
      // 派发暂停状态变化事件
      this.dispatchEvent('sseAudioPlayer:pauseStateChanged', { 
        isPaused: false,
        action: 'resume'
      });

      // 如果有暂停的缓冲区，继续播放当前缓冲区
      if (this.pausedBuffer) {
        this.playAudioChunk(this.pausedBuffer).then(() => {
          // 继续处理队列中的其他音频块
          this.processAudioQueue();
        });
      } else if (this.audioQueue.length > 0) {
        // 否则开始处理队列中的下一个音频块
        this.processAudioQueue();
      }
    } else {
      // 暂停播放
      this.isPaused = true;
      
      // 派发暂停状态变化事件
      this.dispatchEvent('sseAudioPlayer:pauseStateChanged', { 
        isPaused: true,
        action: 'pause'
      });

      // 记录当前播放位置并停止当前音频源
      if (this.audioSource && this.audioSource.buffer) {
        this.pausedPosition = this.audioContext.currentTime;
        this.pausedBuffer = this.audioSource.buffer;
        try {
          this.audioSource.stop();
        } catch (e) {
          console.warn('停止音频源时出错:', e);
        }
        this.audioSource = null;
      } else if (this.audioSource) {
        // 如果audioSource存在但没有buffer，也清除它
        try {
          this.audioSource.stop();
        } catch (e) {
          console.warn('停止音频源时出错:', e);
        }
        this.audioSource = null;
      }
    }
  }

    // 获取音频流
    fetchAudioStream(formData) {
      const url = `${this.config.host}${this.config.endpoint}?t=${Date.now()}`;

      // 派发连接中状态事件
      this.dispatchEvent('sseAudioPlayer:connecting', {
        url: url,
        formData: formData
      });

      // 调试信息
      console.log('发送请求到:', url);
      console.log('请求体:', JSON.stringify(formData));
      console.log('设备信息:', navigator.userAgent);

      // 创建 AbortController 用于控制请求
      this.sseAbortController = new AbortController();

      const headers = {
        'Content-Type': 'application/json',
        'Accept': 'text/event-stream',
        'sign': '59ff66d0798de2ca415f03b22f6b22d4',
        'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
        'Pragma': 'no-cache',
        'Expires': '0',
        'Connection': 'keep-alive',
        'Keep-Alive': 'timeout=120, max=1000'
      };

      // iOS Safari 特殊处理
      const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
      if (isIOS) {
        console.log('✓ 检测到 iOS 设备，应用 iOS 优化策略');
        // iOS 需要更频繁的数据交互来保持连接
        headers['X-iOS-Client'] = 'true';
      }

      // 发送POST请求
      fetch(url, {
        method: 'POST',
        headers: headers,
        body: JSON.stringify(formData),
        signal: this.sseAbortController.signal,
        // iOS 优化：禁用缓存
        cache: 'no-store',
        // 保持连接活跃
        keepalive: false
      })
        .then(response => {
          // 记录响应信息
          console.log('响应状态:', response.status);
          console.log('响应头:', [...response.headers.entries()]);

          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }

          // 派发连接成功事件
          this.dispatchEvent('sseAudioPlayer:connected', {
            status: response.status
          });

          // 启动心跳检测（iOS 必需）
          this.startHeartbeat();

          // 处理SSE流
          this.processSSEStream(response);
        })
        .catch(error => {
          // 清理心跳
          this.stopHeartbeat();

          // 如果是主动取消，不显示错误
          if (error.name === 'AbortError') {
            console.log('SSE 连接已主动取消');
            return;
          }

          // 处理请求错误
          console.error('SSE 请求错误:', error);
          
          // 派发错误事件
          this.dispatchEvent('sseAudioPlayer:error', {
            message: '请求错误: ' + error.message,
            code: 'FETCH_ERROR',
            error: error
          });

          // iOS 设备尝试重连
          if (isIOS && this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectAttempts++;
            console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
            setTimeout(() => {
              this.fetchAudioStream(formData);
            }, 1000 * this.reconnectAttempts);
          } else {
            this.resetButton();
          }
        });
    }

    // 处理SSE流
    processSSEStream(response) {
      const reader = response.body.getReader();
      this.sseReader = reader; // 保存 reader 引用
      const decoder = new TextDecoder('utf-8');
      let buffer = '';
      const self = this;

      // 检测是否为 iOS 设备
      const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

      // 读取流的函数
      function readStream() {
        // 更新最后接收时间
        self.lastReceivedTime = Date.now();

        reader.read().then(({ done, value }) => {
          if (done) {
            console.log('✓ SSE 流正常结束');
            // 清理心跳
            self.stopHeartbeat();
            // 标记流已结束
            self.streamEnded = true;
            // 处理剩余音频
            self.processRemainingAudio();
            return;
          }

          // 解码并添加到缓冲区
          buffer += decoder.decode(value, { stream: true });

          // iOS 设备：立即处理数据，避免缓冲区过大
          if (isIOS) {
            self.processBufferData(buffer, function (remainingBuffer) {
              buffer = remainingBuffer;
              // 继续读取
              readStream();
            });
          } else {
            // 其他设备：正常处理
            self.processBufferData(buffer, function (remainingBuffer) {
              buffer = remainingBuffer;
              // 继续读取
              readStream();
            });
          }
        }).catch(error => {
          // 清理心跳
          self.stopHeartbeat();

          // 如果是主动取消，不显示错误
          if (error.name === 'AbortError') {
            console.log('SSE 流读取已主动取消');
            return;
          }

          // 处理读取错误
          console.error('SSE 流读取错误:', error);
          
          // 派发错误事件
          self.dispatchEvent('sseAudioPlayer:error', {
            message: '接收数据错误: ' + error.message,
            code: 'STREAM_READ_ERROR',
            error: error
          });

          // iOS 设备尝试重连
          if (isIOS && self.reconnectAttempts < self.maxReconnectAttempts && !self.streamEnded) {
            self.reconnectAttempts++;
            console.log(`⚠️ iOS 连接中断，尝试重连 (${self.reconnectAttempts}/${self.maxReconnectAttempts})...`);
            setTimeout(() => {
              if (self.lastRequestParams) {
                self.fetchAudioStream(self.lastRequestParams);
              }
            }, 1000 * self.reconnectAttempts);
          } else {
            self.resetButton();
          }
        });
      }

      // 开始读取流
      readStream();
    }

    // 处理缓冲区数据
    processBufferData(buffer, callback) {
      const lines = buffer.split('\n');
      const remainingBuffer = lines.pop();

      // 处理每一行
      for (const line of lines) {
        if (line.startsWith('data: ')) {
          // 处理数据行，只有当还未提取第一个数据块时才传递isFirstData=true
          const isFirstData = !this.firstDataExtracted;
          this.handleDataLine(line, isFirstData);
        } else if (line === 'event: end') {
          this.handleEndEvent();
        }
      }

      // 回调处理剩余缓冲区
      callback(remainingBuffer);
    }

    // 处理数据行
    handleDataLine(line, isFirstData = false) {
      const data = line.slice(6); // 移除 'data: ' 前缀

      try {
        // 检查数据有效性
        if (!data || data.trim() === '') {
          console.warn('接收到空数据块');
          return;
        }

        console.log('处理数据行:', data.substring(0, 100) + '...'); // 日志截断，避免过长

        // 尝试解析JSON数据
        let audioData;
        let extractedUrl = null;
        let extractedWorkId = null;

        try {
          const jsonData = JSON.parse(data);
          console.log('成功解析JSON数据，包含的键:', Object.keys(jsonData));

          // 寻找audioData字段，只使用audioData字段，否则使用原始data
          audioData = jsonData.audioData || data;

          // 如果是第一个数据块且尚未提取过，尝试提取url和workId
          if (isFirstData && !this.firstDataExtracted) {
            // 检查所有可能的字段名和路径
            // 直接检查根对象
            if (jsonData.url) {
              extractedUrl = jsonData.url;
              console.log('从根对象提取到URL:', extractedUrl);
            } else if (jsonData.data && jsonData.data.url) {
              extractedUrl = jsonData.data.url;
              console.log('从data.url提取到URL:', extractedUrl);
            } else if (jsonData.result && jsonData.result.url) {
              extractedUrl = jsonData.result.url;
              console.log('从result.url提取到URL:', extractedUrl);
            }

            // 提取workId
            if (jsonData.workId) {
              extractedWorkId = jsonData.workId;
              console.log('从根对象提取到workId:', extractedWorkId);
            } else if (jsonData.data && jsonData.data.workId) {
              extractedWorkId = jsonData.data.workId;
              console.log('从data.workId提取到workId:', extractedWorkId);
            } else if (jsonData.result && jsonData.result.workId) {
              extractedWorkId = jsonData.result.workId;
              console.log('从result.workId提取到workId:', extractedWorkId);
            }

            // 保存到实例属性
            if (extractedUrl) this.firstDataUrl = extractedUrl;
            if (extractedWorkId) this.firstDataWorkId = extractedWorkId;

            // 无论是否找到，都标记已提取过第一个数据块
            this.firstDataExtracted = true;

            // 派发第一个片段读取完成事件
            console.log('派发firstDataExtracted事件:', { url: extractedUrl, workId: extractedWorkId });
            this.dispatchEvent('sseAudioPlayer:firstDataExtracted', { 
              url: extractedUrl, 
              workId: extractedWorkId 
            });

            // 如果提取到了url和workId，说明这是元数据帧，跳过不处理
            if (extractedUrl || extractedWorkId) {
              console.log('跳过元数据帧，包含url/workId但无音频数据');
              return;
            }
          }

          if (jsonData.frameType !== undefined) {
            console.log('帧类型:', jsonData.frameType);
            // 只处理 frameType = 1 的音频流，跳过其他类型
            if (jsonData.frameType !== "1") {
              console.log('跳过非音频帧，frameType:', jsonData.frameType);
              return;
            }
            console.log('处理音频帧，frameType = 1');
          }

          // 如果audioData是对象而不是字符串，说明没有实际音频数据
          if (typeof audioData === 'object') {
            console.log('跳过非音频数据块，audioData是对象:', audioData);
            return;
          }
        } catch (jsonError) {
          // 非JSON格式，直接作为Base64处理
          audioData = data;
          console.warn('无法解析为JSON格式，错误信息:', jsonError.message, '作为纯音频数据处理');

          // 即使是非JSON格式，也要标记第一个数据块已处理
          if (isFirstData && !this.firstDataExtracted) {
            this.firstDataExtracted = true;
            console.log('第一个数据块为非JSON格式，无法提取URL和workId');
            // 派发第一个片段读取完成事件
            this.dispatchEvent('sseAudioPlayer:firstDataExtracted', { 
              url: null, 
              workId: null 
            });
          }
        }

        // 检查音频数据（确保是字符串类型）
        if (!audioData || typeof audioData !== 'string' || audioData.trim() === '') {
          console.warn('接收到空音频数据或非字符串数据');
          return;
        }

        // 解析音频数据并加入合并缓冲区
        const audioBuffer = this.parseBase64AudioData(audioData);
        this.mergeBuffer.push(audioBuffer);
        this.receivedChunkCount++;

        console.log(`已接收第 ${this.receivedChunkCount} 个原始音频块,合并缓冲区中有 ${this.mergeBuffer.length} 个`);

        // 当合并缓冲区达到指定数量或接收到最后一块时,进行合并
        // 如果是流结束或者缓冲区达到指定数量，都进行合并
        if (this.mergeBuffer.length >= this.mergeCount || (this.streamEnded && this.mergeBuffer.length > 0)) {
          // 合并音频块
          const mergedBuffer = this.mergeArrayBuffers(this.mergeBuffer);
          this.audioQueue.push(mergedBuffer);

          console.log(`合并了 ${this.mergeBuffer.length} 个音频块,当前队列中有 ${this.audioQueue.length} 个合并块`);

          // 清空合并缓冲区
          this.mergeBuffer = [];

          // 派发加载进度事件
          this.dispatchEvent('sseAudioPlayer:loadProgress', {
            receivedChunkCount: this.receivedChunkCount,
            audioQueueLength: this.audioQueue.length,
            decodedQueueLength: this.decodedQueue.length,
            mergeBufferLength: 0
          });

          // 触发预解码
          if (!this.isDecoding) {
            this.preDecodeAudio();
          }

          // 根据队列状态和autoPlay标记决定是否播放
          console.log('→ 合并后检查: autoPlay =', this.autoPlay, ', isPlaying =', this.isPlaying);
          
          // 只有在autoPlay为true且正在播放时才继续处理
          if (this.autoPlay && this.isPlaying) {
            if (!this.isProcessing && this.decodedQueue.length > 0) {
              this.processAudioQueue();
            }
          } else if (this.autoPlay && !this.isPlaying && !this.isProcessing) {
            // autoPlay模式下，第一次接收到数据时开始播放
            if ((this.audioQueue.length === 1 && this.decodedQueue.length > 0) ||
              (this.streamEnded && this.decodedQueue.length > 0)) {
              this.playFirstAudioChunk();
            }
          }
        } else {
          // 派发加载进度事件（显示合并缓冲区状态）
          this.dispatchEvent('sseAudioPlayer:loadProgress', {
            receivedChunkCount: this.receivedChunkCount,
            audioQueueLength: this.audioQueue.length,
            decodedQueueLength: this.decodedQueue.length,
            mergeBufferLength: this.mergeBuffer.length,
            mergeCount: this.mergeCount
          });

          // autoPlay模式下，如果是开头的音频块且已有解码数据，即使缓冲区未满也尝试播放以减少延迟
          if (this.autoPlay && !this.initialChunksProcessed && this.decodedQueue.length > 0 && !this.isPlaying && !this.isProcessing) {
            this.playFirstAudioChunk();
            this.initialChunksProcessed = true; // 标记已处理开头音频块
          }
        }
      } catch (e) {
        console.error('处理音频块错误:', e);
        console.error('有问题的数据:', data.substring(0, 200) + '...'); // 日志截断，避免过长
      }
    }

    // 处理剩余音频
    processRemainingAudio() {
      console.log('处理剩余音频数据');

      // 如果合并缓冲区还有剩余音频块,先合并并加入队列
      if (this.mergeBuffer.length > 0) {
        console.log(`流结束时,合并剩余的 ${this.mergeBuffer.length} 个音频块`);
        const mergedBuffer = this.mergeArrayBuffers(this.mergeBuffer);
        this.audioQueue.push(mergedBuffer);
        this.mergeBuffer = [];

        // 派发加载进度事件
        this.dispatchEvent('sseAudioPlayer:loadProgress', {
          receivedChunkCount: this.receivedChunkCount,
          audioQueueLength: this.audioQueue.length,
          decodedQueueLength: this.decodedQueue.length,
          mergeBufferLength: 0
        });

        // 触发预解码
        if (!this.isDecoding) {
          this.preDecodeAudio();
        }

        // 只有在autoPlay为true且正在播放时才继续播放
        if (this.autoPlay && this.isPlaying && !this.isProcessing && this.decodedQueue.length > 0) {
          // 如果正在播放，继续处理队列
          this.processAudioQueue();
        }
      } else {
        // 如果没有剩余音频块，但仍需要确保所有已解码的音频都播放完（仅在已经开始播放的情况下）
        if (this.decodedQueue.length > 0 && !this.isProcessing && this.isPlaying) {
          this.processAudioQueue();
        }
      }
      
      // 标记数据已加载完成
      if (!this.isDataLoaded) {
        this.isDataLoaded = true;
        
        // 派发数据加载完成事件
        this.dispatchEvent('sseAudioPlayer:dataLoadCompleted', {
          totalChunks: this.receivedChunkCount,
          autoPlay: this.autoPlay
        });
      }

      // 检查是否所有音频都已处理完毕
      this.checkPlaybackCompletion();
    }

    // 检查播放是否完成
    checkPlaybackCompletion() {
      console.log('开始检查播放完成状态');
      console.log('当前状态 - audioQueue:', this.audioQueue.length, 'decodedQueue:', this.decodedQueue.length, 'mergeBuffer:', this.mergeBuffer.length);
      console.log('当前状态 - isProcessing:', this.isProcessing, 'isPlaying:', this.isPlaying, 'isPlayingChunk:', this.isPlayingChunk);

      // 使用定时器检查是否所有音频都已播放完成
      const checkInterval = setInterval(() => {
        // 如果所有队列都为空且没有正在处理的音频，说明播放完成
        if (this.audioQueue.length === 0 &&
          this.decodedQueue.length === 0 &&
          this.mergeBuffer.length === 0 &&
          !this.isProcessing &&
          !this.isPlaying &&
          !this.isPlayingChunk) {
          clearInterval(checkInterval);

          console.log('✓ 所有音频播放完成');
          this.resetButton();

          // 派发音频播放完成事件
          this.dispatchEvent('sseAudioPlayer:playCompleted', {
            totalPlaybackTime: this.totalPlaybackTime,
            totalChunks: this.currentChunkIndex
          });
        } else {
          // 如果还有未处理的队列，且正在播放中，尝试继续处理
          if (!this.isProcessing && !this.isPlayingChunk && this.isPlaying) {
            if (this.audioQueue.length > 0 && !this.isDecoding) {
              console.log('检测到未处理的音频队列，触发预解码');
              this.preDecodeAudio();
            }
            if (this.decodedQueue.length > 0) {
              console.log('检测到已解码队列，继续播放');
              this.processAudioQueue();
            }
          }
        }
      }, 100); // 每100毫秒检查一次

      // 设置超时，防止无限等待（仅作为兜底保护，不强制清理）
      setTimeout(() => {
        clearInterval(checkInterval);
        console.log('⚠️ 播放完成检查超时，当前状态:');
        console.log('  audioQueue:', this.audioQueue.length);
        console.log('  decodedQueue:', this.decodedQueue.length);
        console.log('  mergeBuffer:', this.mergeBuffer.length);
        console.log('  isProcessing:', this.isProcessing);
        console.log('  isPlayingChunk:', this.isPlayingChunk);
        console.log('  isDecoding:', this.isDecoding);

        // 如果还有未播放的音频，说明处理流程可能卡住了
        if (this.audioQueue.length > 0 || this.decodedQueue.length > 0 || this.mergeBuffer.length > 0) {
          console.warn('⚠️ 检测到未播放的音频，尝试触发处理');

          // 尝试触发处理，但只在正在播放的情况下
          if (!this.isProcessing && !this.isPlayingChunk && this.isPlaying) {
            if (this.mergeBuffer.length > 0) {
              console.log('→ 处理剩余的合并缓冲区');
              this.processRemainingAudio();
            }
            if (this.audioQueue.length > 0 && !this.isDecoding) {
              console.log('→ 触发预解码剩余音频');
              this.preDecodeAudio();
            }
            if (this.decodedQueue.length > 0) {
              console.log('→ 触发播放已解码音频');
              this.processAudioQueue();
            }

            // 再给一次机会，延长检查时间
            console.log('→ 已触发处理，延长检查时间5秒');
            setTimeout(() => {
              if (this.audioQueue.length === 0 &&
                this.decodedQueue.length === 0 &&
                this.mergeBuffer.length === 0) {
                console.log('✓ 延长检查后确认播放完成');
                this.resetButton();
                
                // 派发音频播放完成事件
                this.dispatchEvent('sseAudioPlayer:playCompleted', {
                  totalPlaybackTime: this.totalPlaybackTime,
                  totalChunks: this.currentChunkIndex
                });
              } else {
                console.error('❌ 音频处理可能存在问题，仍有未播放的音频');
                console.log('  最终状态 - audioQueue:', this.audioQueue.length,
                  'decodedQueue:', this.decodedQueue.length,
                  'mergeBuffer:', this.mergeBuffer.length);
              }
            }, 5000);
          } else {
            console.log('→ 正在处理中，等待处理完成');
          }
        } else {
          // 所有队列都为空，正常完成
          console.log('✓ 超时检查确认播放完成');
          this.resetButton();
                        
          // 派发音频播放完成事件
          this.dispatchEvent('sseAudioPlayer:playCompleted', {
            totalPlaybackTime: this.totalPlaybackTime,
            totalChunks: this.currentChunkIndex
          });
        }
      }, 30000); // 30秒超时（给予足够时间）
    }

    // 处理结束事件
    handleEndEvent() {
      console.log('处理音频播放结束事件');

      // 标记流已结束
      this.streamEnded = true;

      // 处理剩余音频
      this.processRemainingAudio();
    }

    // 解锁 iOS AudioContext（通过播放静默音频）
    unlockAudioContext() {
      const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

      if (!isIOS) {
        return; // 非 iOS 设备不需要解锁
      }

      // 检查 AudioContext 状态
      if (this.audioContext.state === 'suspended') {
        console.log('⚠️ AudioContext 处于 suspended 状态，尝试恢复');
        this.audioContext.resume().then(() => {
          console.log('✓ AudioContext 已恢复');
        }).catch(e => {
          console.error('恢复 AudioContext 失败:', e);
        });
      }

      try {
        // 创建并播放静默音频以解锁 iOS
        const silentBuffer = this.audioContext.createBuffer(1, 1, 22050);
        const silentSource = this.audioContext.createBufferSource();
        silentSource.buffer = silentBuffer;
        silentSource.connect(this.audioContext.destination);
        silentSource.start(0);
        console.log('✓ iOS 静默音频已播放，AudioContext 已解锁');
      } catch (e) {
        console.warn('播放静默音频失败:', e);
      }
    }

    // 启动心跳检测（iOS 必需）
    startHeartbeat() {
      // 清理之前的定时器
      this.stopHeartbeat();

      const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
      if (!isIOS) {
        // 非 iOS 设备不需要心跳检测
        return;
      }

      console.log('✓ 启动 iOS 心跳检测');
      this.lastReceivedTime = Date.now();

      // 每 5 秒检测一次
      this.heartbeatTimer = setInterval(() => {
        const now = Date.now();
        const timeSinceLastReceived = now - this.lastReceivedTime;

        // 如果 15 秒没有收到数据，认为连接已断开
        if (timeSinceLastReceived > 15000 && !this.streamEnded) {
          console.warn('⚠️ 心跳超时，连接可能已断开');
          console.log(`距离上次接收数据: ${timeSinceLastReceived}ms`);

          // 尝试重连
          if (this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectAttempts++;
            console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);

            // 清理当前连接
            this.cleanupSSEConnection();

            // 重新连接
            if (this.lastRequestParams) {
              setTimeout(() => {
                this.fetchAudioStream(this.lastRequestParams);
              }, 1000 * this.reconnectAttempts);
            }
          } else {
            console.error('❌ 重连次数已达上限，放弃重连');
            this.stopHeartbeat();
            
            // 派发错误事件
            this.dispatchEvent('sseAudioPlayer:error', {
              message: '连接已断开',
              code: 'CONNECTION_LOST'
            });
            
            this.resetButton();
          }
        }
      }, 5000);
    }

    // 停止心跳检测
    stopHeartbeat() {
      if (this.heartbeatTimer) {
        clearInterval(this.heartbeatTimer);
        this.heartbeatTimer = null;
        console.log('✓ 停止心跳检测');
      }
    }

    // 清理 SSE 连接
    cleanupSSEConnection() {
      // 取消正在进行的请求
      if (this.sseAbortController) {
        try {
          this.sseAbortController.abort();
          console.log('✓ 已取消 SSE 请求');
        } catch (e) {
          console.warn('取消 SSE 请求时出错:', e);
        }
        this.sseAbortController = null;
      }

      // 关闭 reader
      if (this.sseReader) {
        try {
          this.sseReader.cancel();
          console.log('✓ 已关闭 SSE Reader');
        } catch (e) {
          console.warn('关闭 SSE Reader 时出错:', e);
        }
        this.sseReader = null;
      }

      // 停止心跳检测
      this.stopHeartbeat();
    }

  /**
   * 重新播放音频（外部调用）
   */
  replayAudio() {
    // 检查是否有保存的请求参数
    if (!this.lastRequestParams) {
      console.warn('没有可重新播放的音频');
      this.dispatchEvent('sseAudioPlayer:error', { 
        message: '没有可重新播放的音频',
        code: 'NO_REPLAY_DATA'
      });
      return;
    }

    console.log('执行重新播放操作');

    // 停止当前正在播放的音频
    if (this.audioSource) {
      try {
        this.audioSource.stop();
      } catch (e) {
        console.warn('停止音频源时出错:', e);
      }
      this.audioSource = null;
    }

    // 也要停止可能正在处理的音频
    if (this.isProcessing) {
      this.isProcessing = false;
    }
    if (this.isDecoding) {
      this.isDecoding = false;
    }

    // 清空音频队列和合并缓冲区
    this.audioQueue = [];
    this.mergeBuffer = [];
    this.decodedQueue = [];
    this.receivedChunkCount = 0;

    // 重置音频相关状态
    this.isPlaying = false;
    this.isPaused = false;
    this.isProcessing = false;
    this.isDecoding = false;
    this.currentChunkIndex = 0;
    this.totalPlaybackTime = 0;
    this.startTime = 0;

    // 准备播放环境（自动播放）
    this.preparePlayback();
    this.autoPlay = true;

    // 使用保存的参数重新发送请求
    this.fetchAudioStream(this.lastRequestParams);
  }
}

// 导出为全局变量（兼容性）
if (typeof window !== 'undefined') {
  window.SSEAudioPlayer = SSEAudioPlayer;
}
